<#
.SYNOPSIS
    CAD插件批量打包工具（PowerShell 7优化版）
.DESCRIPTION
    指定解决方案文件夹，自动搜索项目文件并批量生成自解压安装包
.PARAMETER SolutionDir
    解决方案文件夹路径
.PARAMETER BuildType
    指定打包目录类型，支持Debug或Release，不区分大小写（默认：Debug）
#>

param(
    [Parameter(Mandatory = $false, HelpMessage = "指定打包目录（Debug/Release），不区分大小写")]
    [ValidateSet("Debug", "Release", IgnoreCase = $true)]
    [string]$BuildType = "Debug"
)




Add-Type -AssemblyName System.Windows.Forms
$folderBrowser = New-Object System.Windows.Forms.FolderBrowserDialog
$folderBrowser.Description = "请选择解决方案文件夹"
$folderBrowser.ShowNewFolderButton = $false
$dialogResult = $folderBrowser.ShowDialog()
if ($dialogResult -ne [System.Windows.Forms.DialogResult]::OK -or [string]::IsNullOrWhiteSpace($folderBrowser.SelectedPath)) {
    Write-Error "未选择解决方案文件夹，脚本终止。"
    exit 1
}
$SolutionDir = $folderBrowser.SelectedPath




$projectFileExtensions = @(".csproj", ".vbproj", ".fsproj")
$fallbackVersion = "1.0.0"
$gb2312Encoding = [System.Text.Encoding]::GetEncoding(936)

# 检查PowerShell版本
if ($PSVersionTable.PSVersion.Major -lt 7) {
    Write-Error "不支持的PowerShell版本，需要PowerShell 7或更高版本"
    exit 1
}

# 检查WinRAR路径
$winRARPath = if (Test-Path "${env:ProgramFiles}\WinRAR\WinRAR.exe") {
    "${env:ProgramFiles}\WinRAR\WinRAR.exe"
} elseif (Test-Path "${env:ProgramFiles(x86)}\WinRAR\WinRAR.exe") {
    "${env:ProgramFiles(x86)}\WinRAR\WinRAR.exe"
} else {
    Write-Error "未找到WinRAR安装路径，请先安装WinRAR"
    exit 1
}

# 搜索所有项目文件
Write-Host "`n=== 自动搜索项目文件 ==="
$projectFiles = Get-ChildItem -Path $SolutionDir -Recurse -File | Where-Object { $projectFileExtensions -contains $_.Extension }
if ($projectFiles.Count -eq 0) {
    Write-Error "未找到任何项目文件，请检查解决方案文件夹路径"
    exit 1
}
# 读取解决方案级版本号
$solutionVersion = $null
$propsFile = Join-Path $SolutionDir "Directory.Build.props"
if (Test-Path $propsFile) {
    try {
        [xml]$propsXml = Get-Content $propsFile -Raw
        $versionNode = $propsXml.SelectSingleNode("//Version")
        if ($versionNode -and -not [string]::IsNullOrEmpty($versionNode.InnerText.Trim())) {
            $solutionVersion = $versionNode.InnerText.Trim()
        }
    } catch {
        Write-Warning "读取Directory.Build.props失败: $($_.Exception.Message)"
    }
}

foreach ($projectFile in $projectFiles) {
    try {
        $projectName = $projectFile.BaseName
        $projectDir = $projectFile.Directory.FullName
        $cadVersion = if ($projectName -match '(ACAD|ZCAD)') { $matches[1] } else { 'ACAD' }
        $formattedBuildType = $BuildType.Substring(0,1).ToUpper() + $BuildType.Substring(1).ToLower()
        Write-Host "`n=== 处理项目: $projectName ==="

        # 优先使用解决方案版本号
        $version = $solutionVersion

        # 如果解决方案版本号不存在，则查找项目文件和AssemblyInfo.cs
        if (-not $version) {
            [xml]$projXml = Get-Content $projectFile.FullName -Raw -ErrorAction Stop
            $versionXPaths = @(
                "//PropertyGroup/Version",
                "//PropertyGroup/AssemblyVersion",
                "//PropertyGroup/FileVersion",
                "//Version",
                "//AssemblyVersion",
                "//FileVersion"
            )
            foreach ($xpath in $versionXPaths) {
                $versionNode = $projXml.SelectSingleNode($xpath)
                if ($versionNode -and -not [string]::IsNullOrEmpty($versionNode.InnerText.Trim())) {
                    $version = $versionNode.InnerText.Trim()
                    break
                }
            }
            if (-not $version) {
                $assemblyInfoPath = Join-Path $projectDir "Properties\AssemblyInfo.cs"
                if (Test-Path $assemblyInfoPath) {
                    $assemblyInfo = Get-Content $assemblyInfoPath -Raw
                    if ($assemblyInfo -match '\[assembly: AssemblyVersion\("(.*?)"\)') {
                        $version = $matches[1]
                    }
                }
            }
        }
        if (-not $version -or [string]::IsNullOrEmpty($version)) {
            $version = $fallbackVersion
        }

        $buildDir = [System.IO.Path]::GetFullPath((Join-Path $projectDir "bin\$formattedBuildType"))
        $outputDir = [System.IO.Path]::GetFullPath((Join-Path $projectDir "bin"))
        $outputExeName = "$projectName-$version-$cadVersion-$formattedBuildType.exe"
        $outputExePath = [System.IO.Path]::GetFullPath((Join-Path $outputDir $outputExeName))

        if (-not (Test-Path -Path $buildDir -PathType Container)) {
            Write-Warning "${formattedBuildType}目录不存在: $buildDir，跳过该项目"
            continue
        }

        # 复制安装脚本
        $installScriptName = if ($cadVersion -eq 'ZCAD') { "installzcad.ps1" } else { "installacad.ps1" }
        $sourceInstallScript = Join-Path $PSScriptRoot $installScriptName
        $destInstallScript = Join-Path $buildDir $installScriptName
        if (-not (Test-Path -Path $sourceInstallScript -PathType Leaf)) {
            Write-Warning "未找到安装脚本: $sourceInstallScript，跳过该项目"
            continue
        }
        Copy-Item -Path $sourceInstallScript -Destination $destInstallScript -Force

        # 文件数量校验
        $fileCount = (Get-ChildItem -Path $buildDir -File -Recurse).Count
        if ($fileCount -eq 0) {
            Write-Warning "$formattedBuildType目录中没有文件，跳过该项目"
            continue
        }

        # 创建输出目录
        if (-not (Test-Path -Path $outputDir)) {
            $null = New-Item -Path $outputDir -ItemType Directory -Force
        }

        # 创建WinRAR配置文件
        $configFile = [System.IO.Path]::GetTempFileName()
        $configContent = @"
;The comment below contains SFX script commands
Setup=powershell -ExecutionPolicy Bypass -NoProfile -WindowStyle Hidden -File $installScriptName -ProjectName $projectName
Silent=0
Overwrite=1
Stay=1
Title=安装 $projectName v$version （$formattedBuildType 版）
"@
        [System.IO.File]::WriteAllText($configFile, $configContent, $gb2312Encoding)
        Write-Host $configContent

        # 安装脚本追加确认代码
        $confirmationCode = @"
# 安装完成后显示确认对话框（增加一行提示）
Add-Type -AssemblyName PresentationFramework
[System.Windows.MessageBox]::Show(
    "$projectName v$version 已成功安装完成！`n`n点击确认后，请重启CAD软件以加载新插件。",
    "安装完成",
    [System.Windows.MessageBoxButton]::OK,
    [System.Windows.MessageBoxImage]::Information,
    [System.Windows.MessageBoxResult]::OK,
    [System.Windows.MessageBoxOptions]::DefaultDesktopOnly
)
"@
        $existingContent = [System.IO.File]::ReadAllText($destInstallScript, $gb2312Encoding)
        $newContent = $existingContent + $confirmationCode
        [System.IO.File]::WriteAllText($destInstallScript, $newContent, $gb2312Encoding)

        # 执行WinRAR命令（参数顺序调整，避免路径和配置文件引号问题）
        $arguments = @(
            "a",
            "-r",
            "-sfx",
            "-z$($configFile)",
            "-ep1",
            "-m5",
            "-y",
            "`"$outputExePath`"",
            "`"$buildDir\*`""
        )
        $process = Start-Process -FilePath $winRARPath -ArgumentList $arguments -Wait -PassThru -NoNewWindow
        $exitCode = $process.ExitCode


        if ($exitCode -eq 0) {
            Write-Host "`n✅ 自解压文件创建成功: $outputExePath"
        } else {
            Write-Warning "❌ WinRAR执行失败，错误代码: $exitCode"
            Write-Warning "请检查WinRAR命令行和SFX配置文件内容是否正确。"
        }

        # 清理临时文件
        if ($configFile -and (Test-Path -Path $configFile)) {
            Remove-Item -Path $configFile -Force -ErrorAction SilentlyContinue
        }
    }
    catch {
        Write-Warning "项目 $($projectFile.FullName) 打包失败: $($_.Exception.Message)"
    }
}